from matplotlib import pyplot, rcParams, rc_file_defaults

class MPLInterface(object):
    '''Matplotlib common interface'''

    def __init__(self, **kwargs):
        self._mplif_attr = {'axesprops':  (0.175, 0.15, 0.8, 0.72),
                            'usetex': True,
                            'rcparams': {},
                            'axes': None,
                            'tag': None,
                            'ext': ['png'],
                            }


        self._mplif_attr.update(kwargs)

        self._mplif_curaxes = None;
        self._mplif_curkwargs = {}

    def draw(self, **kwargs):
        # Set up rc params
        for attr in self._mplif_attr:
            if attr not in kwargs:
                kwargs[attr] = self._mplif_attr[attr]

        self._mplif_curkwargs = kwargs

        mplif_kw = {}
        other_kw = {}
        for kw in kwargs:
            if kw in self._mplif_attr:
                mplif_kw[kw] = kwargs[kw]
            else:
                other_kw[kw] = kwargs[kw]
        
        self._mplif_create()        
        self._mplif_plot(mplif_kw, other_kw)
        self._mplif_label()

        return self._mplif_curaxes
    
    def image(self, **kwargs):
        """
        Save a hard copy of the current Matplotlib drawing.

        Optional Parameters
        -------------------

        out  : string
            Specify a filename for the histogram to be written as
        ext   : {'png' , 'gif' , 'jpg'}
            Specify extension(s) of the image type the histogram is written as
        usetex : bool
            Use LaTeX to render text output
        """

        if not self._mplif_curaxes:
            self.draw(**kwargs)
        
        rcParams['text.usetex'] = self._mplif_curkwargs['usetex']
      
        # save output file
        retname = None
        
        fnext = self._mplif_curkwargs['out'][-3:].lower()
        if fnext in 'png jpg gif pdf svg eps'.split():
            pyplot.savefig(self._mplif_curkwargs['out'])
            retname = self._mplif_curkwargs['out']
        else:
            retname = []
            exts = pyplot.gcf().canvas.get_supported_filetypes().keys()
            for ext in exts:
                if ext not in self._mplif_curkwargs['ext']:
                    continue

                outname = '.'.join([self._mplif_curkwargs['out'], ext])
                pyplot.savefig(outname)
                retname.append(outname)
    
        return self._mplif_curaxes, retname
  


    def show(self, **kwargs):
        if not self._mplif_curaxes:
            self.draw(**kwargs)

        if 'ioff' in self._mplif_curkwargs and self._mplif_curkwargs['ioff']:
            del self._mplif_curkwargs['ioff']
        else:
            pyplot.ion()

        pyplot.show()

        return self._mplif_curaxes

        # Do show stuff

    def _mplif_create(self):
        if self._mplif_curkwargs['rcparams'] is not None:
            rcParams.update(self._mplif_curkwargs['rcparams'])
    
        if self._mplif_curkwargs['axes'] is None:
            fig  = pyplot.figure()
            self._mplif_curkwargs['axes'] = \
                fig.add_axes(self._mplif_curkwargs['axesprops'])
            
        pyplot.sca(self._mplif_curkwargs['axes'])    
        self._mplif_curaxes = self._mplif_curkwargs['axes']

    
    def _mplif_plot(self, mplif_kw, other_kw):
        msg = "MPLIFInterface subclasses are supposed to implement this"
        raise NotImplementedError(msg)

    def _mplif_label(self):
        if 'xlabel' in self._mplif_curkwargs and \
                self._mplif_curkwargs['xlabel']:
            pyplot.xlabel(self._mplif_curkwargs['xlabel'])
        if 'ylabel' in self._mplif_curkwargs and \
                self._mplif_curkwargs['ylabel']:
            pyplot.ylabel(self._mplif_curkwargs['ylabel'])
       
        if 'title' in self._mplif_curkwargs and self._mplif_curkwargs['title']:
            if self._mplif_curkwargs['tag']:
                pyplot.title(self._mplif_curkwargs['title']
                             + '({})'.format(self._mplif_curkwargs['tag']))
            else:
                pyplot.title(self._mplif_curkwargs['title'])


    def wipe(self):
        pyplot.clf()
        rc_file_defaults()
        self._mplif_curaxes = None
        self._mplif_curkwargs = {}


    def __getattribute__(self, name):
        try:
            return super(MPLInterface, self).__getattribute__(name)
        except AttributeError:
            if '_mplif_attr' in self.__dict__ and \
                    name in self.__dict__['_mplif_attr']:
                return self.__dict__['_mplif_attr'][name]
            else:
                raise
        
    def __setattr__(self, name, value):
        try:
            self.__dict__['_mplif_attr'][name] = value
        except KeyError:
            super(MPLInterface, self).__setattr__(name, value)
    
